﻿namespace DCHealthCheck.MvcWeb.Classes {

    #region Usings
    using DCHealthCheck.Common;
    using DCHealthCheck.DomainModel;
    using log4net;
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Threading;
    using System.Web;
    #endregion

    public class Global {

        public const string AdminRole = @"AGRP-DCHealthCheck-ADMIN";
        public const string ApplicationName = "DCHealthCheck";
        public static bool ApplicationUnavailable { get; internal set; }
        public static ILog DefaultLog { get; private set; }
        public static bool Initialized { get; private set; }
        public const string UserRoles = @"CONTOSO\GRP-DCHealthCheckViewOnly";

        static Global() {
            Global.DefaultLog = log4net.LogManager.GetLogger("defaultLogger");
            Global.DefaultLog.InfoFormat("[ThreadId: {0}] {1} ", Thread.CurrentThread.ManagedThreadId, Extensions.CurrentMethodName());

            Log4netTraceListener log4netTraceListener = new Log4netTraceListener(DefaultLog);
            if (!Trace.Listeners.Contains(log4netTraceListener)) Trace.Listeners.Add(log4netTraceListener);
        }

        public static void Initialize() {
            Global.DefaultLog.InfoFormat("[ThreadId: {0}] {1} ", Thread.CurrentThread.ManagedThreadId, Extensions.CurrentMethodName());
            DateTime startTime = DateTime.UtcNow;

            if (Initialized) {
                Global.DefaultLog.WarnFormat("[ThreadId: {0}] {1} Not performing initialization due to we are already initialized.",
                    Thread.CurrentThread.ManagedThreadId, Extensions.CurrentMethodName());
                return;
            }

            try {
                Global.DefaultLog.InfoFormat("[ThreadId: {0}] {1} Initializing Database.", Thread.CurrentThread.ManagedThreadId, Extensions.CurrentMethodName());
                InitializeDatabase();
                Initialized = true;
            }
            catch (Exception e) {
                Global.DefaultLog.Fatal("Error occurred during initialization. - aborting startup." + e.VerboseExceptionString());
                Global.ApplicationUnavailable = true;
            }
            finally {
                Global.DefaultLog.InfoFormat("[ThreadId: {0}] {1} Application startup finished.  Elapsed time: {2}",
                    Thread.CurrentThread.ManagedThreadId, Extensions.CurrentMethodName(), DateTime.UtcNow.Subtract(startTime).ToString());
            }
        }

        private static void InitializeDatabase() {
            Global.DefaultLog.InfoFormat("[ThreadId: {0}] {1} ", Thread.CurrentThread.ManagedThreadId, Extensions.CurrentMethodName());

            using (var entityManager = new EntityManager()) {
                string message = string.Empty;
                if ((entityManager.QuerySets.DomainControllersSlim.Count() == 0)) {
                    message = "No DomainControllers found in database!";
                }

                if (!string.IsNullOrWhiteSpace(message)) {
                    Global.DefaultLog.FatalFormat(message);
                    throw new ApplicationException(message);
                }
            }
        }
    }
}